/*
 +-----------------------------------------------------------------------------------------------+
 | Project : UKAPI
 +-----------------------------------------------------------------------------------------------+
 | Project Description : Universal & Kernel API
 +-----------------------------------------------------------------------------------------------+
 | File Description :
 |   Macros
 |                                                 
 +-----------------------------------------------------------------------------------------------+
 | Licence : MIT Licence
 +-----------------------------------------------------------------------------------------------+
 | Copyright (c) 2006 Olivier Vanhoucke
 | 
 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
 | and associated documentation files (the "Software"), to deal in the Software without 
 | restriction, including without limitation the rights to use, copy, modify, merge, publish, 
 | distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 
 | Software is furnished to do so, subject to the following conditions:
 | 
 | The above copyright notice and this permission notice shall be included in all copies or 
 | substantial portions of the Software.
 | 
 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
 | BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 +-----------------------------------------------------------------------------------------------+
*/

#ifndef __UKAPI_MACROS__
#define __UKAPI_MACROS__

#ifndef CALLBACK
	//#define CALLBACK
#endif /* CALLBACK */

#ifndef __callback
	//#define __callback
#endif /* __callback */

#ifndef __unused
	#define __unused
#endif /* __unused */

#ifndef countof
	#define countof( a )		( sizeof( a ) / sizeof( *a ) )
#endif /* countof */

#ifndef maximum
	#define maximum( a, b )		( ( (a) > (b) ) ? (a) : (b) )
#endif /* maximum */

#ifndef minimum
	#define minimum( a, b )		( ( (a) < (b) ) ? (a) : (b) )
#endif /* minimum */

#ifndef null
	#ifdef __cplusplus
		#define null    0
	#else
		#define null    ( (pointer_t) 0 )
	#endif
#endif

#define		EQ		==		/* is equal to					*/
#define		GE		>=		/* is greater than or equal to	*/
#define		GT		>		/* is greater than				*/
#define		LE		<=		/* is less than or equal to		*/
#define		LT		<		/* is less than					*/
#define		NE		!=		/* is not equal to				*/
#define		AND		&&		/* expression and				*/
#define		OR		||		/* expression or				*/
#define		bAND	&		/* logic and					*/
#define		bOR		|		/* logic or						*/
#define		NOT		!		/* logic not					*/
#define		XOR		^		/* exclusive or					*/
#define		CPL		~		/* complement					*/

#ifndef is_whitespace
	#define is_whitespace( c )			( ( ( c ) == ' ' ) || ( ( c ) == '\t' ) )
#endif /* is_whitespace */

#ifndef is_space
	#define is_space( c )				( ( c ) == ' '  )
#endif /* is_space */

#ifndef is_printable_digit
	#define is_printable_digit( c )		( ( ( c ) >= ' ' ) && ( ( c ) <= '~' ) )
#endif /* is_printable_digit */

#ifndef is_decimal_digit
	#define is_decimal_digit( c )		( ( ( c ) >= '0' ) && ( ( c ) <= '9' ) )
#endif /* is_decimal_digit */

#ifndef is_octal_digit
	#define is_octal_digit( c )			( ( ( c ) >= '0' ) && ( ( c ) <= '7' ) )
#endif /* is_octal_digit */

#ifndef is_hexadecimal_digit
	#define is_hexadecimal_digit( c )	(isdigit((c)) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F'))
#endif /* is_hexadecimal_digit */

#ifndef is_alpha_digit
	#define is_alpha_digit( c )			( ( ( ( c ) >= 'A' ) && ( ( c ) <= 'Z' ) ) || ( ( ( c ) >= 'a' ) && ( ( c ) <= 'z' ) ) )
#endif /* is_alpha_digit */

#ifndef is_alphanumeric_digit
	#define is_alphanumeric_digit( c )	( is_decimal_digit( ( c ) ) || is_alpha_digit( ( c ) ) )
#endif /* is_alphanumeric_digit */

#ifndef decimal_value
	#define decimal_value( c )			( ( c ) - '0' )
#endif /* decimal_value */

#ifndef octal_value
	#define octal_value( c )			( decimal_value( ( c ) ) )
#endif /* octal_value */

#ifndef hexadecimal_value
	#define hexadecimal_value( c )	\
		(((c) >= 'a' && (c) <= 'f') \
  			? (c)-'a'+10 \
  			: (c) >= 'A' && (c) <= 'F' ? (c)-'A'+10 : (c)-'0')
#endif /* hexadecimal_value */

#ifndef char_ascii_to_lower
	#define char_ascii_to_lower( c )     ( ( ( ( c ) >= 'A' ) && ( ( c ) <= 'Z' ) ) ? ( ( c ) ^ 0x20 ) : ( c ) )
#endif /* char_ascii_to_lower */

#ifndef char_ascii_to_upper
	#define char_ascii_to_upper( c )     ( ( ( ( c ) >= 'a' ) && ( ( c ) <= 'z' ) ) ? ( ( c ) ^ 0x20 ) : ( c ) )
#endif /* char_ascii_to_upper */

#ifndef text
	#define text( s )     L##s
#endif /* text */

/*
 * define a macro to compute the size of a type, variable or expression,
 * rounded up to the nearest multiple of sizeof(int). This number is its
 * size as function argument (Intel architecture). Note that the macro
 * depends on sizeof(int) being a power of 2!
 */
#define intsizeof( n )    ( (sizeof( n ) + sizeof( int ) - 1) & ~( sizeof( int ) - 1 ) )

#ifdef  __cplusplus
	#define addressof( v )   ( &reinterpret_cast<const char &>( v ) )
#else
	#define addressof( v )   ( &( v ) )
#endif

#define varg_start( ap, v )		( ap = (va_list_t) addressof( v ) + intsizeof( v ) )
#define varg_arg( ap, t )		( *(t *) ( ( ap += intsizeof( t ) ) - intsizeof( t ) ) )
#define varg_end( ap )			( ap = (va_list_t) 0 )

// Conversion Little-Endian <--> Big-Endian

#define swap_short( val )	( ( ( val & 0xff00 ) >> 8 ) | ( ( val & 0x00ff ) << 8 ) )
#define swap_long( val )	( ( ( val & 0xff000000 ) >> 24 ) | ( ( val & 0x00ff0000 ) >> 8 ) | ( ( val & 0x0000ff00 ) << 8 ) | ( ( val & 0x000000ff ) << 24 ) )
#define swap_double( val )  ( val )

/*
double_t swap_double( double_t val )
{
	register pulong_t ptr, tmp0, tmp1;

	ptr = (pulong_t) &val;
	tmp0 = *(ptr + 0);
	tmp1 = *(ptr + 1);
	*(ptr + 0) = swap_long( tmp1 );
	*(ptr + 1) = swap_long( tmp0 );

	return val;
}
*/

#endif /* __UKAPI_MACROS__ */
